/**
 * 
 * @param {object} obj  发送请求需要的参数
 * obj = {
 *  method: '请求方式，默认为get'
 *  url: '请求路径，必填，'
 *  async: 是否异步的布尔值，默认为true
 *  dataType: 指定响应回来的的数据是什么格式，json/text/xml,默认json
 *  success(res) {} 请求成功要执行的函数
 *  error(err) {}  请求失败后要执行的函数
 * }
 * 
 */
function request(obj) {

    // 限制各个数据

    // 请求路径
    return new Promise((resolve, reject) => {
        if (obj.url === undefined) {
            throw new Error('请求路径不能为空！')
        }
        // 判断类型
        if (typeof obj.url != 'string') {
            throw new Error('请求路径错误！')
        }
        // dataType
        if (obj.dataType == undefined) {
            obj.dataType = 'json'
        }
        // 请求方式 - get/put/post/delete都可以，大小写都可以，可以不传，默认get
        if (obj.method === undefined) {
            // 默认值给get
            obj.method = 'get'
        }
        // 说明get传递了 - 限制是否是这4种方式
        if (obj.method.toLowerCase() != 'get' && obj.method.toLowerCase() != 'post' && obj.method.toLowerCase() != 'put' && obj.method.toLowerCase() != 'delete') {
            // 抛出自定义错误
            throw new Error('请求方式不正确！')
        }

        // async验证
        if (obj.async === undefined) {
            obj.async = true
        }
        if (typeof obj.async != 'boolean') {
            throw new Error('同步false异步true！')
        }



        // data - 可以是字符串，方便传递的话，给对象更好 
        // ajax语法中要求必须是查询字符串 - 如果是对象，需要转成查询字符串
        let data
        if (obj.data != undefined) {
            if (Object.prototype.toString.call(obj.data) === '[object Object]') {
                // 对象 - 转字符串
                let arr = []
                for (let key in obj.data) {
                    arr.push(key + '=' + obj.data[key])
                }
                data = arr.join('&')
            } else if (Object.prototype.toString.call(obj.data) === '[object String]') {
                // 字符串
                data = obj.data
            } else {
                throw new Error('data是字符串或对象！')
            }
            // 判断请求方式是否是get
            if (obj.method.toLowerCase() === 'get') {
                obj.url += '?' + data
            }
        }

        var xhr = new XMLHttpRequest
        xhr.open(obj.method, obj.url, obj.async)
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    let res
                    switch (obj.dataType) {
                        case 'xml':
                            res = xhr.responseXML
                            break
                        case 'json':
                            res = xhr.responseText
                            res = JSON.parse(res)
                            break
                        case 'text':
                            res = xhr.responseText
                            break
                        default:
                            throw new Error('dataType必须是json/text/xml！')
                    }
                    // res = xhr.responseText
                    resolve(res)
                } else {
                    reject('错误')
                }
            }
        }
        // 如果obj中有headers，就遍历并设置请求
        for (let key in obj.headers) {
            xhr.setRequestHeader(key, obj.headers[key])
        }
        if (obj.method.toLowerCase() === 'post' && data) {
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
            xhr.send(data)
            return
        }
        xhr.send()
    })
}